import { Component, forwardRef, Input } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { exists, formatNumber, getO, missing } from '../../../utils/utils';
import { ExpressionService } from '@core/services/expression/ExpressionService';

@Component({
  selector: 'apes-span',
  template: `
    <div class="apes-span">
      <input class="{{prefixCls}}-input
                    {{prefixCls}}-span-disabled"

             [ngModel]="value" disabled="true"
             [ngStyle]="style"/>
      <div *ngIf="showHideBtn"
           class="span-showHidden-icon" (click)="openShowHidden()">
        <i *ngIf="!showHidden" apes-icon apesType="eye-invisible"></i>
        <i *ngIf="showHidden" apes-icon apesType="eye"></i>
      </div>
      <div *ngIf="showTooltip"
           class="apes-span-tooltip"
           apes-tooltip
           [apesTooltipTrigger]="null"
           [apesTooltipTitle]="titleTemplate"></div>
      <ng-template #titleTemplate>
        <div [innerHTML]="value"></div>
      </ng-template>
      <div *ngIf="showIcon && value"
           class="apes-span-icon">
        <i apes-icon
           [ngClass]="{'apes-span-icon-tooltip':showIconTooltip() }"
           [apesType]="showIcon"
           [apes-tooltip]="showIconTooltip()"
           [apesTooltipTitle]="showIconTooltip() ? iconTemplate : null"></i>
        <ng-template #iconTemplate>
          <div [innerHTML]="showIconTooltip()"></div>
        </ng-template>
      </div>
    </div>
  `,
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => ApesSpanComponent),
      multi: true,
    },
  ],
  styles: [`
    .apes-span {
      position: relative;
      display: flex;
      justify-content: space-between;
    }

    .span-showHidden-icon {
      cursor: pointer;
      position: relative;
      top: 5px;
      z-index: 100;
    }

    .apes-span-tooltip {
      position: absolute;
      width: 100%;
      height: 100%;
      z-index: 1;
    }

    .apes-span-icon {
      display: flex;
      align-items: center;
      position: relative;
      top: 2px;
    }

    .apes-span-icon-tooltip {
      cursor: pointer;
    }
  `],
})
// | dataFormat:dispalyFormat
export class ApesSpanComponent implements ControlValueAccessor {
  prefixCls = 'apes';
  private _value: any;
  private _style: any;


  @Input()
  displayFormat = ['value.name'];

  @Input() ctx: any;

  initValue: any;
  showHideBtn: boolean = false;
  _showHidden: boolean = false;
  @Input() hiddenRegExp: any;
  @Input() replaceValue: any;

  @Input() showTooltip: boolean = false;

  @Input() showIconTooltipFormatter: any;
  @Input() showIcon: any;

  constructor(protected expressionService: ExpressionService) {
  }

  @Input() get style(): any {
    return this._style;
  }

  set style(value: any) {
    if (value) {
      this._style = getO(value);
    }
  }

  @Input()
  get value(): any {
    return this._value;
  }

  set value(value: any) {
    if ((this._value === value) || ((this._value == null) && (value == null))) {
      return;
    }
    this._value = value;
    this.initValue = value;
    this.controlChange(value);  // 触发值改变事件，冒泡给父级 | dataFormat
  }

  @Input() get showHidden() {
    return this._showHidden;
  };

  set showHidden(value: boolean) {
    if (value != null) {
      this.showHideBtn = true;
      this._showHidden = value;
    }
  }

  handleInput(val: string): void {
    this.controlChange(val);
  }

  writeValue(value: any): void {
    this.initValue = value;
    let title;
    if (this.showHideBtn && !this.showHidden) {
      let hiddenRegExp = this.hiddenRegExp;
      if (hiddenRegExp) {
        let replaceValue = this.replaceValue;
        let regExpValue = this.display(value, this.displayFormat);
        // tslint:disable-next-line:no-eval
        hiddenRegExp = eval(hiddenRegExp);
        title = regExpValue.replace(hiddenRegExp, replaceValue);
      } else {
        title = '****';
      }
    } else {
      title = this.display(value, this.displayFormat);
    }
    this._value = title;
  }

  display(value: any, args: string[]): any {
    if (missing(value)) return '';
    for (let expression of args) {
      if (missing(expression)) continue;
      let result;
      if (expression == 'currency') {
        result = '￥' + formatNumber(value, 2);
      } else if (expression == 'number') {
        result = formatNumber(value, 2);
      } else {
        result = this.expressionService.evaluate(expression, {
          context: this.ctx,
          model: this.ctx.model,
          value: value,
        });
      }
      if (exists(result)) return result;
    }
    return value;
  }

  registerOnChange(fn: Function): void {
    this.controlChange = fn;
  }

  registerOnTouched(fn: Function): void {
    this.controlTouch = fn;
  }

  public controlChange: Function = () => {
  };
  public controlTouch: Function = () => {
  };

  openShowHidden() {
    this.showHidden = !this.showHidden;
    let value;
    if (this.showHideBtn && !this.showHidden) {
      let hiddenRegExp = this.hiddenRegExp;
      if (hiddenRegExp) {
        let replaceValue = this.replaceValue;
        let regExpValue = this.display(this.initValue, this.displayFormat);
        // tslint:disable-next-line:no-eval
        hiddenRegExp = eval(hiddenRegExp);
        value = regExpValue.replace(hiddenRegExp, replaceValue);
      } else {
        value = '****';
      }
    } else {
      value = this.display(this.initValue, this.displayFormat);
    }
    this._value = value;
  }

  showIconTooltip() {
    if (!this.showIconTooltipFormatter) return null;
    let expression = this.showIconTooltipFormatter;
    let result = this.expressionService.evaluate(expression, {
      context: this.ctx,
      model: this.ctx.model,
      value: this._value,
    });
    return result;
  }
}
